package com.lifeverse.service;

import com.lifeverse.entity.PerformanceMetric;
import com.lifeverse.entity.enums.MetricStatus;
import com.lifeverse.entity.enums.MetricType;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 性能优化服务
 * 提供性能分析、优化建议和自动优化功能
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class PerformanceOptimizationService {
    
    private final PerformanceMonitoringService performanceMonitoringService;
    
    /**
     * 性能优化建议
     */
    public static class OptimizationRecommendation {
        private String category;
        private String title;
        private String description;
        private String priority;
        private String impact;
        private List<String> actions;
        private Map<String, Object> evidence;
        
        public OptimizationRecommendation(String category, String title, String description) {
            this.category = category;
            this.title = title;
            this.description = description;
            this.actions = new ArrayList<>();
            this.evidence = new HashMap<>();
        }
        
        // Getters and Setters
        public String getCategory() { return category; }
        public void setCategory(String category) { this.category = category; }
        
        public String getTitle() { return title; }
        public void setTitle(String title) { this.title = title; }
        
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        
        public String getPriority() { return priority; }
        public void setPriority(String priority) { this.priority = priority; }
        
        public String getImpact() { return impact; }
        public void setImpact(String impact) { this.impact = impact; }
        
        public List<String> getActions() { return actions; }
        public void setActions(List<String> actions) { this.actions = actions; }
        
        public Map<String, Object> getEvidence() { return evidence; }
        public void setEvidence(Map<String, Object> evidence) { this.evidence = evidence; }
    }
    
    /**
     * 性能分析报告
     */
    public static class PerformanceAnalysisReport {
        private LocalDateTime generatedAt;
        private LocalDateTime analysisStartTime;
        private LocalDateTime analysisEndTime;
        private String overallStatus;
        private Double performanceScore;
        private List<OptimizationRecommendation> recommendations;
        private Map<String, Object> metrics;
        private Map<String, Object> trends;
        
        public PerformanceAnalysisReport() {
            this.generatedAt = LocalDateTime.now();
            this.recommendations = new ArrayList<>();
            this.metrics = new HashMap<>();
            this.trends = new HashMap<>();
        }
        
        // Getters and Setters
        public LocalDateTime getGeneratedAt() { return generatedAt; }
        public void setGeneratedAt(LocalDateTime generatedAt) { this.generatedAt = generatedAt; }
        
        public LocalDateTime getAnalysisStartTime() { return analysisStartTime; }
        public void setAnalysisStartTime(LocalDateTime analysisStartTime) { this.analysisStartTime = analysisStartTime; }
        
        public LocalDateTime getAnalysisEndTime() { return analysisEndTime; }
        public void setAnalysisEndTime(LocalDateTime analysisEndTime) { this.analysisEndTime = analysisEndTime; }
        
        public String getOverallStatus() { return overallStatus; }
        public void setOverallStatus(String overallStatus) { this.overallStatus = overallStatus; }
        
        public Double getPerformanceScore() { return performanceScore; }
        public void setPerformanceScore(Double performanceScore) { this.performanceScore = performanceScore; }
        
        public List<OptimizationRecommendation> getRecommendations() { return recommendations; }
        public void setRecommendations(List<OptimizationRecommendation> recommendations) { this.recommendations = recommendations; }
        
        public Map<String, Object> getMetrics() { return metrics; }
        public void setMetrics(Map<String, Object> metrics) { this.metrics = metrics; }
        
        public Map<String, Object> getTrends() { return trends; }
        public void setTrends(Map<String, Object> trends) { this.trends = trends; }
    }
    
    /**
     * 生成性能分析报告
     */
    public PerformanceAnalysisReport generatePerformanceAnalysisReport(LocalDateTime startTime, LocalDateTime endTime) {
        PerformanceAnalysisReport report = new PerformanceAnalysisReport();
        report.setAnalysisStartTime(startTime);
        report.setAnalysisEndTime(endTime);
        
        try {
            // 获取系统健康概览
            Map<String, Object> healthOverview = performanceMonitoringService.getSystemHealthOverview();
            report.getMetrics().putAll(healthOverview);
            
            // 获取性能趋势摘要
            List<Map<String, Object>> trendSummary = performanceMonitoringService.getPerformanceTrendSummary(startTime, endTime);
            report.getTrends().put("trendSummary", trendSummary);
            
            // 分析性能问题并生成建议
            List<OptimizationRecommendation> recommendations = analyzePerformanceIssues(startTime, endTime);
            report.setRecommendations(recommendations);
            
            // 计算性能评分
            Double performanceScore = calculatePerformanceScore(healthOverview, recommendations);
            report.setPerformanceScore(performanceScore);
            
            // 确定整体状态
            String overallStatus = determineOverallStatus(performanceScore, recommendations);
            report.setOverallStatus(overallStatus);
            
        } catch (Exception e) {
            log.error("生成性能分析报告失败", e);
            report.setOverallStatus("ERROR");
        }
        
        return report;
    }
    
    /**
     * 分析性能问题
     */
    private List<OptimizationRecommendation> analyzePerformanceIssues(LocalDateTime startTime, LocalDateTime endTime) {
        List<OptimizationRecommendation> recommendations = new ArrayList<>();
        
        try {
            // 分析CPU性能
            recommendations.addAll(analyzeCpuPerformance(startTime, endTime));
            
            // 分析内存性能
            recommendations.addAll(analyzeMemoryPerformance(startTime, endTime));
            
            // 分析JVM性能
            recommendations.addAll(analyzeJvmPerformance(startTime, endTime));
            
            // 分析响应时间
            recommendations.addAll(analyzeResponseTimePerformance(startTime, endTime));
            
            // 分析数据库性能
            recommendations.addAll(analyzeDatabasePerformance(startTime, endTime));
            
            // 分析缓存性能
            recommendations.addAll(analyzeCachePerformance(startTime, endTime));
            
        } catch (Exception e) {
            log.error("分析性能问题失败", e);
        }
        
        return recommendations;
    }
    
    /**
     * 分析CPU性能
     */
    private List<OptimizationRecommendation> analyzeCpuPerformance(LocalDateTime startTime, LocalDateTime endTime) {
        List<OptimizationRecommendation> recommendations = new ArrayList<>();
        
        try {
            Map<String, Object> cpuStats = performanceMonitoringService.getMetricStatistics("cpu_usage", startTime, endTime);
            BigDecimal avgCpuUsage = (BigDecimal) cpuStats.get("avgValue");
            BigDecimal maxCpuUsage = (BigDecimal) cpuStats.get("maxValue");
            
            if (avgCpuUsage.compareTo(BigDecimal.valueOf(70)) > 0) {
                OptimizationRecommendation recommendation = new OptimizationRecommendation(
                        "CPU", "CPU使用率过高", "平均CPU使用率超过70%，需要优化");
                recommendation.setPriority("HIGH");
                recommendation.setImpact("PERFORMANCE");
                recommendation.getActions().add("检查CPU密集型任务");
                recommendation.getActions().add("优化算法复杂度");
                recommendation.getActions().add("考虑增加CPU资源");
                recommendation.getEvidence().put("avgCpuUsage", avgCpuUsage);
                recommendation.getEvidence().put("maxCpuUsage", maxCpuUsage);
                recommendations.add(recommendation);
            }
            
            if (maxCpuUsage.compareTo(BigDecimal.valueOf(95)) > 0) {
                OptimizationRecommendation recommendation = new OptimizationRecommendation(
                        "CPU", "CPU峰值过高", "CPU使用率峰值超过95%，可能导致系统响应缓慢");
                recommendation.setPriority("CRITICAL");
                recommendation.setImpact("AVAILABILITY");
                recommendation.getActions().add("分析CPU峰值时间点的任务");
                recommendation.getActions().add("实施负载均衡");
                recommendation.getActions().add("优化并发处理");
                recommendation.getEvidence().put("maxCpuUsage", maxCpuUsage);
                recommendations.add(recommendation);
            }
            
        } catch (Exception e) {
            log.error("分析CPU性能失败", e);
        }
        
        return recommendations;
    }
    
    /**
     * 分析内存性能
     */
    private List<OptimizationRecommendation> analyzeMemoryPerformance(LocalDateTime startTime, LocalDateTime endTime) {
        List<OptimizationRecommendation> recommendations = new ArrayList<>();
        
        try {
            Map<String, Object> memoryStats = performanceMonitoringService.getMetricStatistics("memory_usage", startTime, endTime);
            BigDecimal avgMemoryUsage = (BigDecimal) memoryStats.get("avgValue");
            BigDecimal maxMemoryUsage = (BigDecimal) memoryStats.get("maxValue");
            
            if (avgMemoryUsage.compareTo(BigDecimal.valueOf(80)) > 0) {
                OptimizationRecommendation recommendation = new OptimizationRecommendation(
                        "MEMORY", "内存使用率过高", "平均内存使用率超过80%，可能影响性能");
                recommendation.setPriority("HIGH");
                recommendation.setImpact("PERFORMANCE");
                recommendation.getActions().add("检查内存泄漏");
                recommendation.getActions().add("优化数据结构");
                recommendation.getActions().add("增加内存资源");
                recommendation.getEvidence().put("avgMemoryUsage", avgMemoryUsage);
                recommendation.getEvidence().put("maxMemoryUsage", maxMemoryUsage);
                recommendations.add(recommendation);
            }
            
        } catch (Exception e) {
            log.error("分析内存性能失败", e);
        }
        
        return recommendations;
    }
    
    /**
     * 分析JVM性能
     */
    private List<OptimizationRecommendation> analyzeJvmPerformance(LocalDateTime startTime, LocalDateTime endTime) {
        List<OptimizationRecommendation> recommendations = new ArrayList<>();
        
        try {
            Map<String, Object> heapStats = performanceMonitoringService.getMetricStatistics("jvm_heap_usage", startTime, endTime);
            BigDecimal avgHeapUsage = (BigDecimal) heapStats.get("avgValue");
            
            if (avgHeapUsage.compareTo(BigDecimal.valueOf(85)) > 0) {
                OptimizationRecommendation recommendation = new OptimizationRecommendation(
                        "JVM", "JVM堆内存使用率过高", "JVM堆内存使用率过高，可能导致频繁GC");
                recommendation.setPriority("HIGH");
                recommendation.setImpact("PERFORMANCE");
                recommendation.getActions().add("调整JVM堆大小");
                recommendation.getActions().add("优化GC策略");
                recommendation.getActions().add("检查对象生命周期");
                recommendation.getEvidence().put("avgHeapUsage", avgHeapUsage);
                recommendations.add(recommendation);
            }
            
        } catch (Exception e) {
            log.error("分析JVM性能失败", e);
        }
        
        return recommendations;
    }
    
    /**
     * 分析响应时间性能
     */
    private List<OptimizationRecommendation> analyzeResponseTimePerformance(LocalDateTime startTime, LocalDateTime endTime) {
        List<OptimizationRecommendation> recommendations = new ArrayList<>();
        
        try {
            Map<String, Object> responseTimeStats = performanceMonitoringService.getMetricStatistics("response_time", startTime, endTime);
            BigDecimal avgResponseTime = (BigDecimal) responseTimeStats.get("avgValue");
            BigDecimal maxResponseTime = (BigDecimal) responseTimeStats.get("maxValue");
            
            if (avgResponseTime.compareTo(BigDecimal.valueOf(1000)) > 0) {
                OptimizationRecommendation recommendation = new OptimizationRecommendation(
                        "RESPONSE_TIME", "响应时间过长", "平均响应时间超过1秒，影响用户体验");
                recommendation.setPriority("MEDIUM");
                recommendation.setImpact("USER_EXPERIENCE");
                recommendation.getActions().add("优化数据库查询");
                recommendation.getActions().add("增加缓存");
                recommendation.getActions().add("优化业务逻辑");
                recommendation.getEvidence().put("avgResponseTime", avgResponseTime);
                recommendation.getEvidence().put("maxResponseTime", maxResponseTime);
                recommendations.add(recommendation);
            }
            
        } catch (Exception e) {
            log.error("分析响应时间性能失败", e);
        }
        
        return recommendations;
    }
    
    /**
     * 分析数据库性能
     */
    private List<OptimizationRecommendation> analyzeDatabasePerformance(LocalDateTime startTime, LocalDateTime endTime) {
        List<OptimizationRecommendation> recommendations = new ArrayList<>();
        
        try {
            Map<String, Object> dbQueryTimeStats = performanceMonitoringService.getMetricStatistics("db_query_time", startTime, endTime);
            BigDecimal avgQueryTime = (BigDecimal) dbQueryTimeStats.get("avgValue");
            
            if (avgQueryTime.compareTo(BigDecimal.valueOf(500)) > 0) {
                OptimizationRecommendation recommendation = new OptimizationRecommendation(
                        "DATABASE", "数据库查询时间过长", "平均数据库查询时间超过500ms");
                recommendation.setPriority("HIGH");
                recommendation.setImpact("PERFORMANCE");
                recommendation.getActions().add("优化SQL查询");
                recommendation.getActions().add("添加数据库索引");
                recommendation.getActions().add("考虑数据库分片");
                recommendation.getEvidence().put("avgQueryTime", avgQueryTime);
                recommendations.add(recommendation);
            }
            
        } catch (Exception e) {
            log.error("分析数据库性能失败", e);
        }
        
        return recommendations;
    }
    
    /**
     * 分析缓存性能
     */
    private List<OptimizationRecommendation> analyzeCachePerformance(LocalDateTime startTime, LocalDateTime endTime) {
        List<OptimizationRecommendation> recommendations = new ArrayList<>();
        
        try {
            Map<String, Object> cacheHitRateStats = performanceMonitoringService.getMetricStatistics("cache_hit_rate", startTime, endTime);
            BigDecimal avgHitRate = (BigDecimal) cacheHitRateStats.get("avgValue");
            
            if (avgHitRate.compareTo(BigDecimal.valueOf(80)) < 0) {
                OptimizationRecommendation recommendation = new OptimizationRecommendation(
                        "CACHE", "缓存命中率过低", "缓存命中率低于80%，影响性能");
                recommendation.setPriority("MEDIUM");
                recommendation.setImpact("PERFORMANCE");
                recommendation.getActions().add("优化缓存策略");
                recommendation.getActions().add("增加缓存容量");
                recommendation.getActions().add("调整缓存过期时间");
                recommendation.getEvidence().put("avgHitRate", avgHitRate);
                recommendations.add(recommendation);
            }
            
        } catch (Exception e) {
            log.error("分析缓存性能失败", e);
        }
        
        return recommendations;
    }
    
    /**
     * 计算性能评分
     */
    private Double calculatePerformanceScore(Map<String, Object> healthOverview, List<OptimizationRecommendation> recommendations) {
        try {
            // 基础健康评分
            BigDecimal healthScore = (BigDecimal) healthOverview.get("healthScore");
            double baseScore = healthScore != null ? healthScore.doubleValue() : 50.0;
            
            // 根据建议数量和优先级调整评分
            double penalty = 0.0;
            for (OptimizationRecommendation recommendation : recommendations) {
                switch (recommendation.getPriority()) {
                    case "CRITICAL":
                        penalty += 20.0;
                        break;
                    case "HIGH":
                        penalty += 10.0;
                        break;
                    case "MEDIUM":
                        penalty += 5.0;
                        break;
                    case "LOW":
                        penalty += 2.0;
                        break;
                }
            }
            
            double finalScore = Math.max(0.0, baseScore - penalty);
            return Math.min(100.0, finalScore);
            
        } catch (Exception e) {
            log.error("计算性能评分失败", e);
            return 50.0; // 默认评分
        }
    }
    
    /**
     * 确定整体状态
     */
    private String determineOverallStatus(Double performanceScore, List<OptimizationRecommendation> recommendations) {
        if (performanceScore >= 90.0) {
            return "EXCELLENT";
        } else if (performanceScore >= 80.0) {
            return "GOOD";
        } else if (performanceScore >= 70.0) {
            return "FAIR";
        } else if (performanceScore >= 60.0) {
            return "POOR";
        } else {
            return "CRITICAL";
        }
    }
    
    /**
     * 自动性能优化
     */
    @Scheduled(fixedRate = 300000) // 每5分钟执行一次
    public void performAutoOptimization() {
        try {
            LocalDateTime endTime = LocalDateTime.now();
            LocalDateTime startTime = endTime.minusMinutes(30); // 分析最近30分钟
            
            List<OptimizationRecommendation> recommendations = analyzePerformanceIssues(startTime, endTime);
            
            // 执行自动优化操作
            for (OptimizationRecommendation recommendation : recommendations) {
                if ("CRITICAL".equals(recommendation.getPriority())) {
                    executeAutoOptimization(recommendation);
                }
            }
            
        } catch (Exception e) {
            log.error("自动性能优化失败", e);
        }
    }
    
    /**
     * 执行自动优化
     */
    private void executeAutoOptimization(OptimizationRecommendation recommendation) {
        try {
            switch (recommendation.getCategory()) {
                case "CACHE":
                    optimizeCache();
                    break;
                case "MEMORY":
                    optimizeMemory();
                    break;
                case "JVM":
                    optimizeJvm();
                    break;
                default:
                    log.info("暂不支持自动优化类别: {}", recommendation.getCategory());
                    break;
            }
        } catch (Exception e) {
            log.error("执行自动优化失败: category={}", recommendation.getCategory(), e);
        }
    }
    
    /**
     * 优化缓存
     */
    @CacheEvict(allEntries = true, cacheNames = {"performanceMetrics", "systemHealth"})
    private void optimizeCache() {
        log.info("执行缓存优化：清理所有缓存");
        // 这里可以添加更多缓存优化逻辑
    }
    
    /**
     * 优化内存
     */
    private void optimizeMemory() {
        log.info("执行内存优化：触发垃圾回收");
        System.gc(); // 建议JVM进行垃圾回收
        // 这里可以添加更多内存优化逻辑
    }
    
    /**
     * 优化JVM
     */
    private void optimizeJvm() {
        log.info("执行JVM优化");
        // 这里可以添加JVM优化逻辑，如调整线程池大小等
    }
    
    /**
     * 获取性能优化建议
     */
    @Cacheable(value = "performanceRecommendations", key = "#startTime.toString() + '_' + #endTime.toString()")
    public List<OptimizationRecommendation> getOptimizationRecommendations(LocalDateTime startTime, LocalDateTime endTime) {
        return analyzePerformanceIssues(startTime, endTime);
    }
}